APPLICATION FRAMEWORK FOR PSION SERIES 3.        (v24Oct92)
=========================================
By: John Hind. (CompuServe 70374,756)

INTRODUCTION
============
FRAME.OPO is a suite of routines that support message-based, event-driven
application programming on the PSION Series 3 pocket computer. Using the
framework makes application coding much easier and less error-prone. The
framework includes support for time-based applications that cannot
otherwise be done without machine code.

The application programmer needs to write a main routine using the
APPLICATION SKELLETON below and a number of callback procedures (CALLBACK
ROUTINES below).

FIRST LOOK
==========
The distribution archive contains the following files:

FRAME.OPO   - Compiled framework module.
FRAME.OPL   - Commented framework source code.
FTEST.OPL   - Source code for example & test program.
FRAME.TXT   - This file.

To run the example program, first copy FRAME.OPO into an \OPO directory
on your S3. Then copy FTEST.OPL into the \OPL directory, open it and
translate. On completion, run directly or from the RUN OPL icon.

The test program may be modified to produce an application (OPA) file in
the \APP directory. Just remove the REM commands from the lines between the
APP and ENDA statements inclusive and re-translate. To run this, first copy
the FRAME.OPO file to the \APP directory and then install the FTEST 
application using PSION-I from the system level. Note that the sample
application uses the OPL files in the OPL directory an a convenient example.
It will not actually open or modify any files.

Examine the FTEST.OPL application in conjunction with this file to
understand how an application is put together.

FRAME.OPL is provided for advanced users only and you would not normally
need to understand this code to put an application together.

MESSAGES
========
When running, the "fRun:" procedure generates MESSAGES in response to events
from the SERIES 3 operating system. These are in three categories: KEYBOARD,
TIMER and SYSTEM (see below).

Each message has a number, which determines which Callback Routine gets
invoked when that event occurs. When the callback routine is invoked an
integer parameter and a string parameter are set (the parameters are
actually the global variables "fParm%" and "fParm$"). The callback routine
uses these parameters to decide what to do.

Sixteen of the messages are "maskable" - unless these are enabled, the
callback routine will not be invoked. The message mask is set when "fRun:"
is first started and can be changed subsequently by returning a message
from a callback routine. The mask is a bit-map with one bit set
for each message to be enabled. This mask can be assembled by adding together
the values given in the MESSAGE TABLE below.

The message handler callbacks return a message number when complete. This
will normally be either an error message (negative) or 0 (null message) or
100 (exit message). However, the routine can return any message, including
user-defined ones. Care must be taken to avoid infinite loops such as would
happen if a callback routine returned its own message number.

KEYBOARD MESSAGES
=================
There are five keyboard messages:

#4 is invoked when the user presses a hot-key (PSION key with a letter EG 
PSION-S). This message is rarely un-masked as there is a special mechanism
for handling individual hot-keys. A special callback can be provided for
each hot-key used in the application. Hotkeys are enabled and disabled by
including or excluding the letter in the hotkey mask. This mask is set from
a parameter when "fRun:" is started and can subsequently be changed by a
callback routine returning either message #130 or #131. If you use this
mechanism, do NOT enable message #4 as the special callbacks will then not
be invoked.

#5 is invoked when the user makes a keystroke which generates a printable
character such as "a", "A" or "*". This includes SPACE, but excludes ENTER
and DELETE.

#6 is invoked when the user presses one of the "Special" keys such as "up
arrow" "ESC" "ENTER" etc. (see SPECIAL KEY TABLE below).

#9 is invoked when the "MENU" key is pressed. The associated callback would
normally bring up a menu system and then return either message #0 or #4. In
the latter case, the parameters would be set by the callback to the hotkey
of the selected option. The framework will then use the hotkey callback
to activate the option as if the hotkey had been pressed.

#10 is invoked when the "HELP" key is pressed.

For all keyboard messages there is a special additional parameter in the
global variable "fKmod%". This gives the modifier status at the time the
key was pressed as per the OPL KMOD function. This is particularly useful
for detecting shifted special keystrokes.


TIMER MESSAGES
==============
There are two timers: one generates a message every minute and the other
every second. Only one timer may be active at any time.

The timers are started and stopped by masking and unmasking their respective
messages in the usual way. They are synchronised with the Series-3 clock (i.e.
the minute timer message happens just after the minutes have changed on the
clock).

The timers continue to run even if the application is in the background,
however they stop when the SERIES-3 switches off. The message parameter
shows how many units of time have been missed when the SERIES-3 was off,
or was tied up with other things. For stopwatches and similar applications,
the parameter should be added to an accumulator each time the message
callback is invoked. This is important, because the system does not guarantee
that the message will happen every unit of time. Also, the callback may
be called with parameter equal to zero when the timer is synchronising 
and the callback must cope with this.

SYSTEM MESSAGES
===============
Messages #1 to #3 are system messages invoked when the operating system
changes the state of the application. Normally they can be left masked as
all normal house keeping is done by the framework.

Messages #100 and above are not handled by the normal callback mechanism but
may be returned by callback routines to cause the framework to take
appropriate actions.

For file-based applications, the "aOpen%:", "aCreate%" and "aClose%" callbacks
must be provided. The framework handles externally driven file handling using
these routines. For application driven file handling DO NOT call these
callbacks directly, go through the framework by returning the appropriate
messages. #101 should be returned to create a new file. #102 should be
returned to open a new file. In both cases, the file name should be in fParm$.

Messages #129 to #131 can be returned to change the message and hotkey masks
while the application is running. The new value of the message mask should be
in fParm% and the new value of the hotkey mask in fParm$. #129 changes only
the message mask, #130 only the hotkey mask and #131 changes both masks.

APPLICATION SKELLETON
=====================
REM Start of skeleton application

APP skull
 TYPE 3            :REM May be of any type See Programming Manual Cp.11
ENDA

PROC skull:

 REM Global Data required by application

 LOADM "FRAME.OPO"     :REM Load the Application Framework Code.

 REM Application initialisation code (prior to file opening)

 fAutoOff:             :REM Enable auto switch-off for this application.

 fRun:($0100,"AB")     :REM Run the application, Menu key and hotkeys
                        REM PSION-A and PSION-B enabled.
ENDP

REM Application call-back routines

REM Other application routines

REM End of skeleton application

MESSAGE TABLE
=============
Message fParm%	fParm$  Mask   Event
======= ======	======  ====   =====
0                         -    Null (Nothing happened)
1                       $0001  Program was moved to foreground
2                       $0002  Program was moved to background
3                       $0004  Machine was switched on
4       keycode   char  $0008  Hot key was pressed
5       keycode   char  $0010  Printable character was entered
6       keycode         $0020  Special key was pressed
7       seconds         $0040  Seconds timer elapsed
8       minutes         $0080  Minutes timer elapsed
9                       $0100  Menu key was pressed
10                      $0200  Help key was pressed
11-16   app       app    etc.  Application maskable messages
17-99   app       app     -    Application non-maskable messages
100                       -    Exit from application
101            filename   -    Create a new file
102            filename   -    Open an existing file
129     mask              -    Change the message mask
130               mask    -    Change the hotkey mask
131     mask      mask    -    Change both masks

Message fParm%  fParm$         Error
======= ======  ======         =====
-1      ERR       ERR$         OPL System Error
-2             filename        Cannot create file
-3             filename        Cannot open file
-4             filename        Bad filename

SPECIAL KEYCODE TABLE
=====================
Values in fParm%       Modifiers (added together in fKmod%)

Key     Code           Key       Code
===     ====           ===       ====
Esc     27             Shift     $0002
Delete  8              Control   $0004
Tab     9              PSION     $0008
Enter   13             Caps Lock $0010
up      256
down    257
left    259
right   258
Home    262
End     263
PgDn    261
PgUp    260
Dial    803


CALLBACK ROUTINES
=================
These routines MUST be provided for type 2, 3 or 4 OPAs and should return 
0 or error #-2, #-3 or #-4:

aOpen%:       Open a file and perform any per-file initialisation.
aCreate%:     Create a file and perform any per-file initialisation.
aClose%:      Perform any tidy-up and close the current file.

This routine is optional, if provided it should return either 0 or 100, or
pass the error back for handling by the default handler:

aError%:(e%)  Error handler. e% is the error number.

These routines must be provided for all messages below 99 which are defined
and can be unmasked during program execution:

aMh1%: -      Message handlers for messages 1-99 above. Should return 0, a
aMh99%:       error number or another message (NEVER the same message).

These routines must be provided for any Hot Keys which may be unmasked during
program execution:

aHkA%: -      Hot Key handlers for keys A to Z. Should return 0, an error
aHkZ%:        number or another message.


FRAMEWORK ROUTINES
==================
fRun:(mesMsk%,hkMsk$)
              This is the main routine for the Application Framework system.
              It is called from the application's main PROC and, on exiting
              the application run is complete. The parameters are the initial
              values of the Message Mask and the Hotkey mask.

Callback routines (or initialisation code) may themselves call the following
framework routines:

fLock:        Use these before and after any command that waits for user
fUnlock:      keyboard activity I.E. a dialogue box or the menu.

fAutoOff:     Call this to allow the Series 3 to switch off when an                         application using timers is running.

CONDITIONS OF USE
=================
The file FRAME.OPO and the associated documentation and source code is provided as-is and the author will not be liable for any consequences of use.

The copyright on these files is owned by John Hind.

The file FRAME.ZIP may be freely distributed so long as it is unchanged and complete.

The file FRAME.OPO may be freely distributed as part of an application as long as the documentation credits me for my contribution and a copy of the application is provided for my use free of charge.

If an application using FRAME.OPO is sold for profit, a share of the profits must be donated to Amnesty International. The application programmer may assess the proportion based on the relative sizes of the FRAME.OPO file and the application object code file.

I would appreciate any bug reports, comments, ideas or suggestions for the further development of this system.

John Hind (CompuServe 70374,756)
1a Brunswick Quay, Redriff Road, London SE16 1PU, United Kingdom.

END OF DOCUMENT
===============
